2 * Wireshark Memory Manager Array
3 * Copyright 2013, Evan Huus <eapache@gmail.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include "wmem_core.h"
19 #include "wmem_array.h"
21 /* Holds a wmem-allocated array.
22 * elem_len is the size of each element
23 * elem_count is the number of used elements
24 * alloc_count is the length (in elems) of the raw buffer pointed to by buf,
25 * regardless of how many elems are used (the contents)
27 struct _wmem_array_t
{
28 wmem_allocator_t
*allocator
;
41 wmem_array_sized_new(wmem_allocator_t
*allocator
, size_t elem_size
,
46 array
= wmem_new(allocator
, wmem_array_t
);
48 array
->allocator
= allocator
;
49 array
->elem_size
= elem_size
;
50 array
->elem_count
= 0;
51 array
->alloc_count
= alloc_count
? alloc_count
: 1;
52 array
->null_terminated
= false;
54 array
->buf
= (uint8_t *)wmem_alloc(array
->allocator
,
55 array
->elem_size
* array
->alloc_count
);
61 wmem_array_new(wmem_allocator_t
*allocator
, const size_t elem_size
)
65 array
= wmem_array_sized_new(allocator
, elem_size
, 1);
71 wmem_array_grow(wmem_array_t
*array
, const unsigned to_add
)
73 unsigned new_alloc_count
, new_count
;
75 new_alloc_count
= array
->alloc_count
;
76 new_count
= array
->elem_count
+ to_add
;
78 while (new_alloc_count
< new_count
) {
82 if (new_alloc_count
== array
->alloc_count
) {
86 array
->buf
= (uint8_t *)wmem_realloc(array
->allocator
, array
->buf
,
87 new_alloc_count
* array
->elem_size
);
89 array
->alloc_count
= new_alloc_count
;
93 wmem_array_write_null_terminator(wmem_array_t
*array
)
95 if (array
->null_terminated
) {
96 wmem_array_grow(array
, 1);
97 memset(&array
->buf
[array
->elem_count
* array
->elem_size
], 0x0, array
->elem_size
);
102 wmem_array_set_null_terminator(wmem_array_t
*array
)
104 array
->null_terminated
= true;
105 wmem_array_write_null_terminator(array
);
109 wmem_array_bzero(wmem_array_t
*array
)
111 memset(array
->buf
, 0x0, array
->elem_size
* array
->elem_count
);
115 wmem_array_append(wmem_array_t
*array
, const void *in
, unsigned count
)
117 wmem_array_grow(array
, count
);
119 memcpy(&array
->buf
[array
->elem_count
* array
->elem_size
], in
,
120 count
* array
->elem_size
);
122 array
->elem_count
+= count
;
124 wmem_array_write_null_terminator(array
);
128 wmem_array_index(wmem_array_t
*array
, unsigned array_index
)
130 g_assert(array_index
< array
->elem_count
);
131 return &array
->buf
[array_index
* array
->elem_size
];
135 wmem_array_try_index(wmem_array_t
*array
, unsigned array_index
, void *val
)
137 if (array_index
>= array
->elem_count
)
139 memcpy(val
, &array
->buf
[array_index
* array
->elem_size
], array
->elem_size
);
144 wmem_array_sort(wmem_array_t
*array
, int (*compar
)(const void*,const void*))
146 qsort(array
->buf
, array
->elem_count
, array
->elem_size
, compar
);
150 wmem_array_get_raw(wmem_array_t
*array
)
156 wmem_array_get_count(wmem_array_t
*array
)
161 return array
->elem_count
;
165 wmem_array_finalize(wmem_array_t
*array
)
170 size_t used_size
= array
->null_terminated
? (array
->elem_count
+ 1) * array
->elem_size
: array
->elem_count
* array
->elem_size
;
171 void *ret
= wmem_realloc(array
->allocator
, array
->buf
, used_size
);
173 wmem_free(array
->allocator
, array
);
179 wmem_destroy_array(wmem_array_t
*array
)
181 wmem_free(array
->allocator
, array
->buf
);
182 wmem_free(array
->allocator
, array
);
186 * Editor modelines - https://www.wireshark.org/tools/modelines.html
191 * indent-tabs-mode: nil
194 * vi: set shiftwidth=4 tabstop=8 expandtab:
195 * :indentSize=4:tabSize=8:noTabs=true: