Coverage Report

Created: 2026-01-02 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/wsutil/wmem/wmem_list.c
Line
Count
Source
1
/* wmem_list.c
2
 * Wireshark Memory Manager Doubly-Linked List
3
 * Copyright 2012, Evan Huus <eapache@gmail.com>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include <string.h>
13
#include <glib.h>
14
15
#include "wmem_core.h"
16
#include "wmem_list.h"
17
18
struct _wmem_list_frame_t {
19
    struct _wmem_list_frame_t *next, *prev;
20
    void *data;
21
};
22
23
struct _wmem_list_t {
24
    unsigned count;
25
    wmem_list_frame_t  *head, *tail;
26
    wmem_allocator_t   *allocator;
27
};
28
29
unsigned
30
wmem_list_count(const wmem_list_t *list)
31
7.92M
{
32
7.92M
    return list->count;
33
7.92M
}
34
35
wmem_list_frame_t *
36
wmem_list_head(const wmem_list_t *list)
37
397k
{
38
397k
    return list->head;
39
397k
}
40
41
wmem_list_frame_t *
42
wmem_list_tail(const wmem_list_t *list)
43
691k
{
44
691k
    return list->tail;
45
691k
}
46
47
wmem_list_frame_t *
48
wmem_list_frame_next(const wmem_list_frame_t *frame)
49
499k
{
50
499k
    return frame->next;
51
499k
}
52
53
wmem_list_frame_t *
54
wmem_list_frame_prev(const wmem_list_frame_t *frame)
55
290k
{
56
290k
    return frame->prev;
57
290k
}
58
59
void *
60
wmem_list_frame_data(const wmem_list_frame_t *frame)
61
1.30M
{
62
1.30M
    return frame->data;
63
1.30M
}
64
65
void
66
wmem_list_remove(wmem_list_t *list, void *data)
67
134k
{
68
134k
    wmem_list_frame_t *frame;
69
70
134k
    frame = list->head;
71
72
134k
    while (frame && frame->data != data) {
73
0
        frame = frame->next;
74
0
    }
75
76
134k
    if (frame == NULL) {
77
0
        return;
78
0
    }
79
80
134k
    wmem_list_remove_frame(list, frame);
81
134k
}
82
83
void
84
wmem_list_remove_frame(wmem_list_t *list, wmem_list_frame_t *frame)
85
673k
{
86
673k
    if (frame->prev) {
87
538k
        frame->prev->next = frame->next;
88
538k
    }
89
134k
    else {
90
134k
        list->head = frame->next;
91
134k
    }
92
93
673k
    if (frame->next) {
94
98.6k
        frame->next->prev = frame->prev;
95
98.6k
    }
96
574k
    else {
97
574k
        list->tail = frame->prev;
98
574k
    }
99
100
673k
    list->count--;
101
673k
    wmem_free(list->allocator, frame);
102
673k
}
103
104
wmem_list_frame_t *
105
wmem_list_find(const wmem_list_t *list, const void *data)
106
10.5k
{
107
10.5k
    wmem_list_frame_t *cur;
108
109
69.8k
    for (cur = list->head; cur; cur = cur->next) {
110
59.2k
        if(cur->data == data)
111
0
            return cur;
112
59.2k
    }
113
114
10.5k
    return NULL;
115
10.5k
}
116
117
wmem_list_frame_t *
118
wmem_list_find_custom(const wmem_list_t *list, const void *data, GCompareFunc compare_func)
119
10.6k
{
120
10.6k
    wmem_list_frame_t *cur;
121
122
170k
    for (cur = list->head; cur != NULL; cur = cur->next) {
123
164k
        if (compare_func(cur->data, data) == 0) {
124
4.49k
            return cur;
125
4.49k
        }
126
164k
    }
127
128
6.16k
    return NULL;
129
10.6k
}
130
131
void
132
wmem_list_prepend(wmem_list_t *list, void *data)
133
234k
{
134
234k
    wmem_list_frame_t *new_frame;
135
136
234k
    new_frame = wmem_new(list->allocator, wmem_list_frame_t);
137
138
234k
    new_frame->data = data;
139
234k
    new_frame->next = list->head;
140
234k
    new_frame->prev = NULL;
141
142
234k
    if (list->head) {
143
113k
        list->head->prev = new_frame;
144
113k
    }
145
121k
    else {
146
121k
        list->tail = new_frame;
147
121k
    }
148
149
234k
    list->head = new_frame;
150
234k
    list->count++;
151
234k
}
152
153
void
154
wmem_list_append(wmem_list_t *list, void *data)
155
2.02M
{
156
2.02M
    wmem_list_frame_t *new_frame;
157
158
2.02M
    new_frame = wmem_new(list->allocator, wmem_list_frame_t);
159
2.02M
    new_frame->data = data;
160
2.02M
    new_frame->next = NULL;
161
2.02M
    new_frame->prev = list->tail;
162
163
2.02M
    if (list->tail) {
164
1.77M
        list->tail->next = new_frame;
165
1.77M
    }
166
255k
    else {
167
255k
        list->head = new_frame;
168
255k
    }
169
170
2.02M
    list->tail = new_frame;
171
2.02M
    list->count++;
172
2.02M
}
173
174
void
175
wmem_list_insert_sorted(wmem_list_t *list, void* data, GCompareFunc func)
176
9.82k
{
177
9.82k
    wmem_list_frame_t *new_frame;
178
9.82k
    wmem_list_frame_t *cur;
179
9.82k
    wmem_list_frame_t *prev;
180
181
9.82k
    new_frame = wmem_new(list->allocator, wmem_list_frame_t);
182
9.82k
    new_frame->data = data;
183
9.82k
    new_frame->next = NULL;
184
9.82k
    new_frame->prev = NULL;
185
186
9.82k
    list->count++;
187
188
9.82k
    if (!list->head) {
189
2.15k
        list->head = new_frame;
190
2.15k
        list->tail = new_frame;
191
2.15k
        return;
192
2.15k
    }
193
194
7.66k
    cur = list->head;
195
196
7.66k
    if (func(cur->data, data) >= 0) {
197
1.69k
        cur->prev = new_frame;
198
1.69k
        new_frame->next = cur;
199
1.69k
        list->head = new_frame;
200
1.69k
        return;
201
1.69k
    }
202
203
343k
    do {
204
343k
        prev = cur;
205
343k
        cur = cur->next;
206
343k
    } while (cur && func(cur->data, data) <= 0);
207
208
5.96k
    if (!cur) {
209
1.34k
        prev->next = new_frame;
210
1.34k
        new_frame->prev = prev;
211
1.34k
        list->tail = new_frame;
212
1.34k
        return;
213
1.34k
    }
214
215
4.61k
    new_frame->prev = prev;
216
4.61k
    new_frame->next = cur;
217
4.61k
    new_frame->prev->next = new_frame;
218
4.61k
    new_frame->next->prev = new_frame;
219
4.61k
}
220
221
void
222
wmem_list_append_sorted(wmem_list_t *list, void* data, GCompareFunc func)
223
0
{
224
0
    wmem_list_frame_t *new_frame;
225
0
    wmem_list_frame_t *cur;
226
0
    wmem_list_frame_t *next;
227
228
0
    new_frame = wmem_new(list->allocator, wmem_list_frame_t);
229
0
    new_frame->data = data;
230
0
    new_frame->next = NULL;
231
0
    new_frame->prev = NULL;
232
233
0
    list->count++;
234
235
0
    if (!list->head) {
236
0
        list->head = new_frame;
237
0
        list->tail = new_frame;
238
0
        return;
239
0
    }
240
241
0
    cur = list->tail;
242
243
    /* best case scenario: append */
244
0
    if (func(cur->data, data) <= 0) {
245
0
        cur->next = new_frame;
246
0
        new_frame->prev = cur;
247
0
        list->tail = new_frame;
248
0
        return;
249
0
    }
250
251
0
    do {
252
0
        next = cur;
253
0
        cur = cur->prev;
254
0
    } while (cur && func(cur->data, data) >= 0);
255
256
    /* worst case scenario: prepend */
257
0
    if (!cur) {
258
0
        next->prev = new_frame;
259
0
        new_frame->next = next;
260
0
        list->head = new_frame;
261
0
        return;
262
0
    }
263
264
    /* ordinary case: insert */
265
0
    new_frame->next = next;
266
0
    new_frame->prev = cur;
267
0
    new_frame->prev->next = new_frame;
268
0
    new_frame->next->prev = new_frame;
269
0
}
270
271
wmem_list_t *
272
wmem_list_new(wmem_allocator_t *allocator)
273
1.44M
{
274
1.44M
    wmem_list_t *list;
275
276
1.44M
    list =  wmem_new(allocator, wmem_list_t);
277
278
1.44M
    list->count     = 0;
279
1.44M
    list->head      = NULL;
280
1.44M
    list->tail      = NULL;
281
1.44M
    list->allocator = allocator;
282
283
1.44M
    return list;
284
1.44M
}
285
286
void
287
wmem_destroy_list(wmem_list_t *list)
288
362k
{
289
362k
    wmem_list_frame_t *cur, *next;
290
291
362k
    cur = list->head;
292
293
385k
    while (cur) {
294
23.5k
        next = cur->next;
295
23.5k
        wmem_free(list->allocator, cur);
296
23.5k
        cur = next;
297
23.5k
    }
298
299
362k
    wmem_free(list->allocator, list);
300
362k
}
301
302
void
303
wmem_list_foreach(const wmem_list_t *list, GFunc foreach_func, void * user_data)
304
501k
{
305
501k
    wmem_list_frame_t *cur;
306
307
501k
    cur = list->head;
308
309
569k
    while (cur) {
310
68.2k
        foreach_func(cur->data, user_data);
311
68.2k
        cur = cur->next;
312
68.2k
    }
313
501k
}
314
315
/*
316
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
317
 *
318
 * Local variables:
319
 * c-basic-offset: 4
320
 * tab-width: 8
321
 * indent-tabs-mode: nil
322
 * End:
323
 *
324
 * vi: set shiftwidth=4 tabstop=8 expandtab:
325
 * :indentSize=4:tabSize=8:noTabs=true:
326
 */