Rizin
unix-like reverse engineering framework and cli tools
idpool.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2017-2020 condret <condr3t@protonmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_util.h>
5 #include <rz_types.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #if __WINDOWS__
9 #include <search.h>
10 #endif
11 
12 static ut32 get_msb(ut32 v) {
13  int i;
14  for (i = 31; i > (-1); i--) {
15  if (v & (0x1U << i)) {
16  return (v & (0x1U << i));
17  }
18  }
19  return 0;
20 }
21 
22 RZ_API RzIDPool *rz_id_pool_new(ut32 start_id, ut32 last_id) {
23  RzIDPool *pool = NULL;
24  if (start_id < last_id) {
25  pool = RZ_NEW0(RzIDPool);
26  if (pool) {
27  pool->next_id = pool->start_id = start_id;
28  pool->last_id = last_id;
29  }
30  }
31  return pool;
32 }
33 
34 RZ_API bool rz_id_pool_grab_id(RzIDPool *pool, ut32 *grabber) {
35  rz_return_val_if_fail(pool && grabber, false);
36 
37  *grabber = UT32_MAX;
38  if (pool->freed_ids) {
39  rz_vector_pop_front(pool->freed_ids, grabber);
40  if (rz_vector_empty(pool->freed_ids)) {
42  }
43  return true;
44  }
45  if (pool->next_id < pool->last_id) {
46  *grabber = pool->next_id;
47  pool->next_id++;
48  return true;
49  }
50  return false;
51 }
52 
54  if (!pool || (kick < pool->start_id) || (pool->start_id == pool->next_id)) {
55  return false;
56  }
57  if (kick == (pool->next_id - 1)) {
58  pool->next_id--;
59  return true;
60  }
61  if (!pool->freed_ids) {
62  pool->freed_ids = rz_vector_new(sizeof(ut32), NULL, NULL);
63  if (!pool->freed_ids) {
64  return false;
65  }
66  rz_vector_reserve(pool->freed_ids, 2);
67  }
68  rz_vector_push(pool->freed_ids, &kick);
69  return true;
70 }
71 
73  if (!pool) {
74  return;
75  }
77  free(pool);
78 }
79 
81  RzIDStorage *storage = NULL;
82  RzIDPool *pool = rz_id_pool_new(start_id, last_id);
83  if (pool) {
84  storage = RZ_NEW0(RzIDStorage);
85  if (!storage) {
86  rz_id_pool_free(pool);
87  return NULL;
88  }
89  storage->pool = pool;
90  }
91  return storage;
92 }
93 
94 static bool id_storage_reallocate(RzIDStorage *storage, ut32 size) {
95  if (!storage) {
96  return false;
97  }
98  void **data = realloc(storage->data, size * sizeof(void *));
99  if (!data) {
100  return false;
101  }
102  if (size > storage->size) {
103  memset(data + storage->size, 0, (size - storage->size) * sizeof(void *));
104  }
105  storage->data = data;
106  storage->size = size;
107  return true;
108 }
109 
111  ut32 *permutation;
112  if (!st) {
113  return false;
114  }
115  if (!size) {
116  RZ_FREE(st->permutation);
117  st->psize = 0;
118  }
119  permutation = realloc(st->permutation, size * sizeof(ut32));
120  if (!permutation) {
121  return false;
122  }
123  if (size > st->psize) {
124  memset(permutation + st->psize, 0, (size - st->psize) * sizeof(ut32));
125  }
126  st->permutation = permutation;
127  st->psize = size;
128  return true;
129 }
130 
131 RZ_API bool rz_id_storage_set(RzIDStorage *storage, void *data, ut32 id) {
132  ut32 n;
133  if (!storage || !storage->pool || (id >= storage->pool->next_id)) {
134  return false;
135  }
136  n = get_msb(id + 1);
137  if (n > ((storage->size / 2) + (storage->size / 4))) {
138  if ((n * 2) < storage->pool->last_id) {
139  if (!id_storage_reallocate(storage, n * 2)) {
140  return false;
141  }
142  } else if (n != (storage->pool->last_id)) {
143  if (!id_storage_reallocate(storage, storage->pool->last_id)) {
144  return false;
145  }
146  }
147  }
148  storage->data[id] = data;
149  if (id > storage->top_id) {
150  storage->top_id = id;
151  }
152  return true;
153 }
154 
155 RZ_API bool rz_id_storage_add(RzIDStorage *storage, void *data, ut32 *id) {
156  if (!storage || !rz_id_pool_grab_id(storage->pool, id)) {
157  return false;
158  }
159  return rz_id_storage_set(storage, data, *id);
160 }
161 
163  if (!storage || !storage->data || (storage->size <= id)) {
164  return NULL;
165  }
166  return storage->data[id];
167 }
168 
170  rz_return_val_if_fail(storage, false);
171  ut32 i;
172  for (i = 0; i < storage->size && !storage->data[i]; i++)
173  ;
174  *id = i;
175  return i < storage->size;
176 }
177 
179  rz_return_val_if_fail(storage, false);
180  size_t i = 0;
181  if (storage->size > 0) {
182  for (i = storage->size - 1; !storage->data[i] && i > 0; i--)
183  ;
184  *id = i;
185  return storage->data[i] != NULL;
186  }
187  // *id = i;
188  return false;
189 }
190 
192  rz_return_val_if_fail(idref && storage, false);
193  ut32 id = *idref;
194  if (storage->size < 1 || id >= storage->size || !storage->data) {
195  return false;
196  }
197  for (id = *idref + 1; id < storage->size && !storage->data[id]; id++)
198  ;
199  if (id < storage->size) {
200  *idref = id;
201  return true;
202  }
203  return false;
204 }
205 
207  rz_return_val_if_fail(idref && storage, false);
208  ut32 id = *idref;
209  if (id == 0 || id >= storage->size || storage->size < 1 || !storage->data) {
210  return false;
211  }
212  for (id = *idref - 1; id > 0 && !storage->data[id]; id--)
213  ;
214  if (storage->data[id]) {
215  *idref = id;
216  return true;
217  }
218  return false;
219 }
220 
222  if (!storage || !storage->data || (storage->size <= id)) {
223  return;
224  }
225  storage->data[id] = NULL;
226  if (id == storage->top_id) {
227  while (storage->top_id && !storage->data[storage->top_id]) {
228  storage->top_id--;
229  }
230  if (!storage->top_id) {
231  if (storage->data[storage->top_id]) {
232  id_storage_reallocate(storage, 2);
233  } else {
234  RzIDPool *pool = rz_id_pool_new(storage->pool->start_id, storage->pool->last_id);
235  RZ_FREE(storage->data);
236  storage->size = 0;
237  rz_id_pool_free(storage->pool);
238  storage->pool = pool;
239  return;
240  }
241  } else if ((storage->top_id + 1) < (storage->size / 4)) {
242  id_storage_reallocate(storage, storage->size / 2);
243  }
244  }
245  rz_id_pool_kick_id(storage->pool, id);
246 }
247 
249  void *ret = rz_id_storage_get(storage, id);
250  rz_id_storage_delete(storage, id);
251  return ret;
252 }
253 
255  ut32 i;
256  if (!cb || !storage || !storage->data) {
257  return false;
258  }
259  for (i = 0; i < storage->top_id; i++) {
260  if (storage->data[i] && !cb(user, storage->data[i], i)) {
261  return false;
262  }
263  }
264  if (storage->data[i]) {
265  return cb(user, storage->data[i], i);
266  }
267  return true;
268 }
269 
271  if (storage) {
272  rz_id_pool_free(storage->pool);
273  free(storage->data);
274  }
275  free(storage);
276 }
277 
278 static bool _list(void *user, void *data, ut32 id) {
279  rz_list_append(user, data);
280  return true;
281 }
282 
286  return list;
287 }
288 
289 RZ_API ROIDStorage *rz_oids_new(ut32 start_id, ut32 last_id) {
290  ROIDStorage *storage = RZ_NEW0(ROIDStorage);
291  if (!storage) {
292  return NULL;
293  }
294  if (!(storage->data = rz_id_storage_new(start_id, last_id))) {
295  free(storage);
296  return NULL;
297  }
298  return storage;
299 }
300 
301 RZ_API void *rz_oids_get(ROIDStorage *storage, ut32 id) {
302  if (storage) {
303  return rz_id_storage_get(storage->data, id);
304  }
305  return NULL;
306 }
307 
308 RZ_API void *rz_oids_oget(ROIDStorage *storage, ut32 od) {
309  ut32 id;
310  if (rz_oids_get_id(storage, od, &id)) {
311  return rz_id_storage_get(storage->data, id);
312  }
313  return NULL;
314 }
315 
316 RZ_API bool rz_oids_get_id(ROIDStorage *storage, ut32 od, ut32 *id) {
317  if (storage && storage->permutation && (storage->ptop > od)) {
318  *id = storage->permutation[od];
319  return true;
320  }
321  return false;
322 }
323 
324 RZ_API bool rz_oids_get_od(ROIDStorage *storage, ut32 id, ut32 *od) {
325  if (storage && storage->permutation &&
326  storage->data && (id < storage->data->pool->next_id)) {
327  for (od[0] = 0; od[0] < storage->ptop; od[0]++) {
328  if (id == storage->permutation[od[0]]) {
329  return true;
330  }
331  }
332  }
333  return false;
334 }
335 
336 RZ_API bool rz_oids_add(ROIDStorage *storage, void *data, ut32 *id, ut32 *od) {
337  if (!storage || !id || !od) {
338  return false;
339  }
340  if (!rz_id_storage_add(storage->data, data, id)) {
341  return false;
342  }
343  if (!storage->permutation) {
344  oid_storage_preallocate(storage, 4);
345  } else if (storage->ptop > (storage->psize * 3 / 4)) {
346  oid_storage_preallocate(storage, storage->psize * 2);
347  }
348  if (storage->psize <= storage->ptop) {
349  rz_id_storage_delete(storage->data, *id);
350  return false;
351  }
352  if (!storage->permutation) {
353  return false;
354  }
355  *od = storage->ptop;
356  storage->permutation[*od] = *id;
357  storage->ptop++;
358  return true;
359 }
360 
361 RZ_API bool rz_oids_to_front(ROIDStorage *storage, const ut32 id) {
362  ut32 od;
363  if (!storage || !storage->permutation) {
364  return false;
365  }
366  for (od = 0; od < storage->ptop; od++) {
367  if (id == storage->permutation[od]) {
368  break;
369  }
370  }
371  if (od == storage->ptop) {
372  return false;
373  } else if (od == (storage->ptop - 1)) {
374  return true;
375  }
376  memmove(&storage->permutation[od], &storage->permutation[od + 1],
377  (storage->ptop - od - 1) * sizeof(ut32));
378  storage->permutation[storage->ptop - 1] = id;
379  return true;
380 }
381 
383  ut32 od;
384  if (!storage || !storage->permutation ||
385  !storage->data || (id >= storage->data->pool->next_id)) {
386  return false;
387  }
388  bool found = false;
389  for (od = 0; od < storage->ptop; od++) {
390  if (id == storage->permutation[od]) {
391  found = true;
392  break;
393  }
394  }
395  if (od == storage->ptop) {
396  return false;
397  }
398  if (!found) {
399  return true;
400  }
401  memmove(&storage->permutation[1], &storage->permutation[0], od * sizeof(ut32));
402  storage->permutation[0] = id;
403  return true;
404 }
405 
406 RZ_API void rz_oids_delete(ROIDStorage *storage, ut32 id) {
407  if (!rz_oids_to_front(storage, id)) {
408  return;
409  }
410  rz_id_storage_delete(storage->data, id);
411  storage->ptop--;
412  if (!storage->ptop) {
413  RZ_FREE(storage->permutation);
414  storage->psize = 0;
415  } else if ((storage->ptop + 1) < (storage->psize / 4)) {
416  oid_storage_preallocate(storage, storage->psize / 2);
417  }
418 }
419 
421  ut32 n;
422  if (!st || !st->permutation || od >= st->ptop) {
423  return;
424  }
425  n = st->ptop - od - 1;
426  rz_id_storage_delete(st->data, st->permutation[od]);
427  memmove(&st->permutation[od], &st->permutation[od + 1], n * sizeof(ut32));
428  st->ptop--;
429  if (!st->ptop) {
430  RZ_FREE(st->permutation);
431  st->psize = 0;
432  } else if ((st->ptop + 1) < (st->psize / 4)) {
433  oid_storage_preallocate(st, st->psize / 2);
434  }
435 }
436 
437 RZ_API void *rz_oids_take(ROIDStorage *storage, ut32 id) {
438  rz_return_val_if_fail(storage, NULL);
439  void *ret = rz_id_storage_get(storage->data, id);
440  rz_oids_delete(storage, id);
441  return ret;
442 }
443 
445  void *ret = rz_oids_oget(st, od);
446  rz_oids_odelete(st, od);
447  return ret;
448 }
449 
451  if (storage) {
452  free(storage->permutation);
453  rz_id_storage_free(storage->data);
454  }
455  free(storage);
456 }
457 
458 // returns the element with lowest order
459 RZ_API void *rz_oids_last(ROIDStorage *storage) {
460  if (storage && storage->data && storage->data->data && storage->permutation) {
461  return storage->data->data[storage->permutation[0]];
462  }
463  return NULL;
464 }
465 
466 // return the element with highest order
468  if (storage && storage->data && storage->data->data && storage->permutation) {
469  return storage->data->data[storage->permutation[storage->ptop - 1]];
470  }
471  return NULL;
472 }
473 
475  ut32 i;
476  ut32 id;
477  if (!cb || !storage || !storage->data || !storage->data->data || !storage->permutation) {
478  return false;
479  }
480  for (i = storage->ptop - 1; i != 0; i--) {
481  id = storage->permutation[i];
482  if (!cb(user, storage->data->data[id], id)) {
483  return false;
484  }
485  }
486  id = storage->permutation[0];
487  return cb(user, storage->data->data[id], id);
488 }
489 
491  ut32 i;
492  ut32 id;
493  if (!cb || !storage || !storage->data || !storage->data->data || !storage->permutation) {
494  return false;
495  }
496  for (i = 0; i < storage->ptop; i++) {
497  id = storage->permutation[i];
498  if (!cb(user, storage->data->data[id], id)) {
499  return false;
500  }
501  }
502  return true;
503 }
504 
505 bool oids_od_bfind(ROIDStorage *st, ut32 *od, void *incoming, void *user) {
506  st64 high, low;
507  int cmp_res;
508  void *in;
509 
510  if (!st->ptop) {
511  return false;
512  }
513 
514  high = st->ptop - 1;
515  low = 0;
516 
517  while (1) {
518  if (high <= low) {
519  od[0] = (ut32)low;
520  in = rz_oids_oget(st, od[0]);
521  // in - incoming
522  if (!st->cmp(in, incoming, user, &cmp_res)) {
523  return false;
524  }
525  if (cmp_res < 0) {
526  od[0]++;
527  }
528  return true;
529  }
530 
531  od[0] = (ut32)((low + high) / 2);
532  in = rz_oids_oget(st, od[0]);
533  if (!st->cmp(in, incoming, user, &cmp_res)) {
534  return false;
535  }
536 
537  if (cmp_res == 0) {
538  return true;
539  }
540 
541  if (cmp_res < 0) {
542  low = od[0] + 1;
543  } else {
544  high = od[0];
545  high--;
546  }
547  }
548  return false;
549 }
550 
551 bool oids_od_binsert(ROIDStorage *storage, ut32 id, ut32 *od, void *incoming, void *user) {
552  if (!oids_od_bfind(storage, od, incoming, user)) {
553  return false;
554  }
555  if (od[0] != storage->ptop) {
556  memmove(&storage->permutation[od[0] + 1], &storage->permutation[od[0]], (storage->ptop - od[0]) * sizeof(ut32));
557  }
558  storage->ptop++;
559  storage->permutation[od[0]] = id;
560  return true;
561 }
562 
563 RZ_API bool rz_oids_insert(ROIDStorage *storage, void *data, ut32 *id, ut32 *od, void *user) {
564  if (!storage || !storage->cmp || !id || !od) {
565  return false;
566  }
567  if (!storage->ptop) { // empty storage
568  return rz_oids_add(storage, data, id, od);
569  }
570  if (!rz_id_storage_add(storage->data, data, id)) {
571  return false;
572  }
573  if (storage->ptop > (storage->psize * 3 / 4)) {
574  oid_storage_preallocate(storage, storage->psize * 2);
575  }
576  return oids_od_binsert(storage, id[0], od, data, user);
577 }
578 
579 RZ_API bool rz_oids_sort(ROIDStorage *storage, void *user) {
580  ut32 od, id, ptop, *permutation;
581 
582  if (!storage || !storage->ptop || !storage->cmp) {
583  return false;
584  }
585  if (storage->ptop == 1) {
586  return true;
587  }
588  permutation = storage->permutation;
589  storage->permutation = RZ_NEWS0(ut32, storage->psize);
590  if (!storage->permutation) {
591  storage->permutation = permutation;
592  return false;
593  }
594  storage->permutation[0] = permutation[0];
595  ptop = storage->ptop;
596  storage->ptop = 1;
597  while (storage->ptop != ptop) {
598  id = permutation[storage->ptop];
599  void *incoming = rz_id_storage_get(storage->data, id);
600  if (!oids_od_binsert(storage, id, &od, incoming, user)) {
601  goto beach;
602  }
603  }
604  free(permutation);
605  return true;
606 
607 beach:
608  free(storage->permutation);
609  storage->permutation = permutation;
610  storage->ptop = ptop;
611  return false;
612 }
613 
614 RZ_API ut32 rz_oids_find(ROIDStorage *storage, void *incoming, void *user) {
615  ut32 ret;
616  return oids_od_bfind(storage, &ret, incoming, user) ? ret : storage->ptop;
617 }
lzma_index ** i
Definition: index.h:629
const lzma_allocator const uint8_t * in
Definition: block.h:527
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
const char * v
Definition: dsignal.c:12
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
RZ_API bool rz_id_storage_get_next(RzIDStorage *storage, ut32 *idref)
Definition: idpool.c:191
RZ_API bool rz_id_storage_set(RzIDStorage *storage, void *data, ut32 id)
Definition: idpool.c:131
RZ_API ROIDStorage * rz_oids_new(ut32 start_id, ut32 last_id)
Definition: idpool.c:289
RZ_API RzIDPool * rz_id_pool_new(ut32 start_id, ut32 last_id)
Definition: idpool.c:22
bool oids_od_bfind(ROIDStorage *st, ut32 *od, void *incoming, void *user)
Definition: idpool.c:505
RZ_API void * rz_oids_otake(ROIDStorage *st, ut32 od)
Definition: idpool.c:444
RZ_API bool rz_oids_get_id(ROIDStorage *storage, ut32 od, ut32 *id)
Definition: idpool.c:316
RZ_API bool rz_id_storage_get_prev(RzIDStorage *storage, ut32 *idref)
Definition: idpool.c:206
static bool id_storage_reallocate(RzIDStorage *storage, ut32 size)
Definition: idpool.c:94
RZ_API bool rz_oids_foreach(ROIDStorage *storage, RzIDStorageForeachCb cb, void *user)
Definition: idpool.c:474
RZ_API void * rz_oids_oget(ROIDStorage *storage, ut32 od)
Definition: idpool.c:308
static bool _list(void *user, void *data, ut32 id)
Definition: idpool.c:278
RZ_API bool rz_id_storage_get_lowest(RzIDStorage *storage, ut32 *id)
Definition: idpool.c:169
RZ_API bool rz_oids_to_rear(ROIDStorage *storage, ut32 id)
Definition: idpool.c:382
RZ_API bool rz_id_pool_grab_id(RzIDPool *pool, ut32 *grabber)
Definition: idpool.c:34
static ut32 get_msb(ut32 v)
Definition: idpool.c:12
RZ_API void * rz_id_storage_take(RzIDStorage *storage, ut32 id)
Definition: idpool.c:248
static bool oid_storage_preallocate(ROIDStorage *st, ut32 size)
Definition: idpool.c:110
RZ_API bool rz_oids_insert(ROIDStorage *storage, void *data, ut32 *id, ut32 *od, void *user)
Definition: idpool.c:563
RZ_API bool rz_oids_to_front(ROIDStorage *storage, const ut32 id)
Definition: idpool.c:361
RZ_API void * rz_oids_take(ROIDStorage *storage, ut32 id)
Definition: idpool.c:437
RZ_API RzIDStorage * rz_id_storage_new(ut32 start_id, ut32 last_id)
Definition: idpool.c:80
RZ_API bool rz_oids_sort(ROIDStorage *storage, void *user)
Definition: idpool.c:579
RZ_API RzList * rz_id_storage_list(RzIDStorage *s)
Definition: idpool.c:283
RZ_API void rz_id_storage_free(RzIDStorage *storage)
Definition: idpool.c:270
RZ_API void * rz_oids_last(ROIDStorage *storage)
Definition: idpool.c:459
RZ_API void rz_oids_free(ROIDStorage *storage)
Definition: idpool.c:450
RZ_API bool rz_oids_get_od(ROIDStorage *storage, ut32 id, ut32 *od)
Definition: idpool.c:324
RZ_API bool rz_oids_foreach_prev(ROIDStorage *storage, RzIDStorageForeachCb cb, void *user)
Definition: idpool.c:490
RZ_API void rz_id_pool_free(RzIDPool *pool)
Definition: idpool.c:72
bool oids_od_binsert(ROIDStorage *storage, ut32 id, ut32 *od, void *incoming, void *user)
Definition: idpool.c:551
RZ_API void * rz_oids_get(ROIDStorage *storage, ut32 id)
Definition: idpool.c:301
RZ_API void * rz_id_storage_get(RzIDStorage *storage, ut32 id)
Definition: idpool.c:162
RZ_API void rz_oids_odelete(ROIDStorage *st, ut32 od)
Definition: idpool.c:420
RZ_API bool rz_id_storage_foreach(RzIDStorage *storage, RzIDStorageForeachCb cb, void *user)
Definition: idpool.c:254
RZ_API void rz_id_storage_delete(RzIDStorage *storage, ut32 id)
Definition: idpool.c:221
RZ_API ut32 rz_oids_find(ROIDStorage *storage, void *incoming, void *user)
Definition: idpool.c:614
RZ_API bool rz_oids_add(ROIDStorage *storage, void *data, ut32 *id, ut32 *od)
Definition: idpool.c:336
RZ_API void rz_oids_delete(ROIDStorage *storage, ut32 id)
Definition: idpool.c:406
RZ_API bool rz_id_storage_add(RzIDStorage *storage, void *data, ut32 *id)
Definition: idpool.c:155
RZ_API void * rz_oids_first(ROIDStorage *storage)
Definition: idpool.c:467
RZ_API bool rz_id_storage_get_highest(RzIDStorage *storage, ut32 *id)
Definition: idpool.c:178
RZ_API bool rz_id_pool_kick_id(RzIDPool *pool, ut32 kick)
Definition: idpool.c:53
voidpf void uLong size
Definition: ioapi.h:138
return memset(p, 0, total)
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
int n
Definition: mipsasm.c:19
int id
Definition: op.c:540
static RzSocket * s
Definition: rtr.c:28
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
bool(* RzIDStorageForeachCb)(void *user, void *data, ut32 id)
Definition: rz_idpool.h:34
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE_CUSTOM(x, y)
Definition: rz_types.h:375
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
#define RZ_FREE(x)
Definition: rz_types.h:369
#define st64
Definition: rz_types_base.h:10
#define UT32_MAX
Definition: rz_types_base.h:99
RZ_API void rz_vector_pop_front(RzVector *vec, void *into)
Definition: vector.c:192
RZ_API void * rz_vector_reserve(RzVector *vec, size_t capacity)
Definition: vector.c:214
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
RZ_API void rz_vector_free(RzVector *vec)
Definition: vector.c:75
RZ_API RzVector * rz_vector_new(size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:42
static bool rz_vector_empty(const RzVector *vec)
Definition: rz_vector.h:74
ut32 start_id
Definition: rz_idpool.h:16
ut32 next_id
Definition: rz_idpool.h:18
ut32 last_id
Definition: rz_idpool.h:17
RzVector * freed_ids
Definition: rz_idpool.h:19
void ** data
Definition: rz_idpool.h:29
RzIDPool * pool
Definition: rz_idpool.h:28
ROIDStorageCompareCb cmp
Definition: rz_idpool.h:56
RzIDStorage * data
Definition: rz_idpool.h:55
static const char * cb[]
Definition: z80_tab.h:176