Rizin
unix-like reverse engineering framework and cli tools
zip_hash.c File Reference
#include "zipint.h"
#include <stdlib.h>
#include <string.h>

Go to the source code of this file.

Classes

struct  zip_hash_entry
 
struct  zip_hash
 

Macros

#define HASH_MULTIPLIER   33
 
#define HASH_START   5381
 
#define HASH_MAX_FILL   .75
 
#define HASH_MIN_FILL   .01
 
#define HASH_MIN_SIZE   256
 
#define HASH_MAX_SIZE   0x80000000ul
 

Typedefs

typedef struct zip_hash_entry zip_hash_entry_t
 

Functions

static void free_list (zip_hash_entry_t *entry)
 
static zip_uint32_t hash_string (const zip_uint8_t *name)
 
static bool hash_resize (zip_hash_t *hash, zip_uint32_t new_size, zip_error_t *error)
 
static zip_uint32_t size_for_capacity (zip_uint64_t capacity)
 
zip_hash_t_zip_hash_new (zip_error_t *error)
 
void _zip_hash_free (zip_hash_t *hash)
 
bool _zip_hash_add (zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip_flags_t flags, zip_error_t *error)
 
bool _zip_hash_delete (zip_hash_t *hash, const zip_uint8_t *name, zip_error_t *error)
 
zip_int64_t _zip_hash_lookup (zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, zip_error_t *error)
 
bool _zip_hash_reserve_capacity (zip_hash_t *hash, zip_uint64_t capacity, zip_error_t *error)
 
bool _zip_hash_revert (zip_hash_t *hash, zip_error_t *error)
 

Macro Definition Documentation

◆ HASH_MAX_FILL

#define HASH_MAX_FILL   .75

Definition at line 43 of file zip_hash.c.

◆ HASH_MAX_SIZE

#define HASH_MAX_SIZE   0x80000000ul

Definition at line 48 of file zip_hash.c.

◆ HASH_MIN_FILL

#define HASH_MIN_FILL   .01

Definition at line 44 of file zip_hash.c.

◆ HASH_MIN_SIZE

#define HASH_MIN_SIZE   256

Definition at line 47 of file zip_hash.c.

◆ HASH_MULTIPLIER

#define HASH_MULTIPLIER   33

Definition at line 39 of file zip_hash.c.

◆ HASH_START

#define HASH_START   5381

Definition at line 40 of file zip_hash.c.

Typedef Documentation

◆ zip_hash_entry_t

Definition at line 1 of file zip_hash.c.

Function Documentation

◆ _zip_hash_add()

bool _zip_hash_add ( zip_hash_t hash,
const zip_uint8_t name,
zip_uint64_t  index,
zip_flags_t  flags,
zip_error_t error 
)

Definition at line 205 of file zip_hash.c.

205  {
206  zip_uint32_t hash_value, table_index;
208 
209  if (hash == NULL || name == NULL || index > ZIP_INT64_MAX) {
211  return false;
212  }
213 
214  if (hash->table_size == 0) {
215  if (!hash_resize(hash, HASH_MIN_SIZE, error)) {
216  return false;
217  }
218  }
219 
220  hash_value = hash_string(name);
221  table_index = hash_value % hash->table_size;
222 
223  for (entry = hash->table[table_index]; entry != NULL; entry = entry->next) {
224  if (entry->hash_value == hash_value && strcmp((const char *)name, (const char *)entry->name) == 0) {
225  if (((flags & ZIP_FL_UNCHANGED) && entry->orig_index != -1) || entry->current_index != -1) {
227  return false;
228  }
229  else {
230  break;
231  }
232  }
233  }
234 
235  if (entry == NULL) {
236  if ((entry = (zip_hash_entry_t *)malloc(sizeof(zip_hash_entry_t))) == NULL) {
238  return false;
239  }
240  entry->name = name;
241  entry->next = hash->table[table_index];
242  hash->table[table_index] = entry;
243  entry->hash_value = hash_value;
244  entry->orig_index = -1;
245  hash->nentries++;
246  if (hash->nentries > hash->table_size * HASH_MAX_FILL && hash->table_size < HASH_MAX_SIZE) {
247  if (!hash_resize(hash, hash->table_size * 2, error)) {
248  return false;
249  }
250  }
251  }
252 
253  if (flags & ZIP_FL_UNCHANGED) {
254  entry->orig_index = (zip_int64_t)index;
255  }
256  entry->current_index = (zip_int64_t)index;
257 
258  return true;
259 }
#define NULL
Definition: cris-opc.c:27
ZIP_EXTERN void zip_error_set(zip_error_t *_Nullable, int, int)
Definition: zip_error.c:126
#define ZIP_ER_MEMORY
Definition: zip.h:119
#define ZIP_ER_EXISTS
Definition: zip.h:115
#define ZIP_ER_INVAL
Definition: zip.h:123
#define ZIP_FL_UNCHANGED
Definition: zip.h:79
void * malloc(size_t size)
Definition: malloc.c:123
const char * name
Definition: op.c:541
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
Definition: zipcmp.c:77
char * name
Definition: zipcmp.c:78
Definition: z80asm.h:102
Definition: zip_hash.c:50
zip_hash_entry_t ** table
Definition: zip_hash.c:62
zip_uint32_t table_size
Definition: zip_hash.c:60
zip_uint64_t nentries
Definition: zip_hash.c:61
void error(const char *msg)
Definition: untgz.c:593
static zip_uint32_t hash_string(const zip_uint8_t *name)
Definition: zip_hash.c:79
#define HASH_MAX_FILL
Definition: zip_hash.c:43
#define HASH_MIN_SIZE
Definition: zip_hash.c:47
static bool hash_resize(zip_hash_t *hash, zip_uint32_t new_size, zip_error_t *error)
Definition: zip_hash.c:97
#define HASH_MAX_SIZE
Definition: zip_hash.c:48
uint32_t zip_uint32_t
Definition: zipconf.h:37
#define ZIP_INT64_MAX
Definition: zipconf.h:54
int64_t zip_int64_t
Definition: zipconf.h:38

References error(), flags, HASH_MAX_FILL, HASH_MAX_SIZE, HASH_MIN_SIZE, hash_resize(), hash_string(), malloc(), name, entry::name, zip_hash::nentries, NULL, zip_hash::table, zip_hash::table_size, ZIP_ER_EXISTS, ZIP_ER_INVAL, ZIP_ER_MEMORY, zip_error_set(), ZIP_FL_UNCHANGED, and ZIP_INT64_MAX.

Referenced by _zip_open(), _zip_set_name(), and _zip_unchange().

◆ _zip_hash_delete()

bool _zip_hash_delete ( zip_hash_t hash,
const zip_uint8_t name,
zip_error_t error 
)

Definition at line 264 of file zip_hash.c.

264  {
265  zip_uint32_t hash_value, index;
266  zip_hash_entry_t *entry, *previous;
267 
268  if (hash == NULL || name == NULL) {
270  return false;
271  }
272 
273  if (hash->nentries > 0) {
274  hash_value = hash_string(name);
275  index = hash_value % hash->table_size;
276  previous = NULL;
277  entry = hash->table[index];
278  while (entry) {
279  if (entry->hash_value == hash_value && strcmp((const char *)name, (const char *)entry->name) == 0) {
280  if (entry->orig_index == -1) {
281  if (previous) {
282  previous->next = entry->next;
283  }
284  else {
285  hash->table[index] = entry->next;
286  }
287  free(entry);
288  hash->nentries--;
289  if (hash->nentries < hash->table_size * HASH_MIN_FILL && hash->table_size > HASH_MIN_SIZE) {
290  if (!hash_resize(hash, hash->table_size / 2, error)) {
291  return false;
292  }
293  }
294  }
295  else {
296  entry->current_index = -1;
297  }
298  return true;
299  }
300  previous = entry;
301  entry = entry->next;
302  }
303  }
304 
306  return false;
307 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define ZIP_ER_NOENT
Definition: zip.h:114
struct zip_hash_entry * next
Definition: zip_hash.c:54
#define HASH_MIN_FILL
Definition: zip_hash.c:44

References error(), free(), HASH_MIN_FILL, HASH_MIN_SIZE, hash_resize(), hash_string(), entry::name, zip_hash::nentries, zip_hash_entry::next, NULL, zip_hash::table, zip_hash::table_size, ZIP_ER_INVAL, ZIP_ER_NOENT, and zip_error_set().

Referenced by _zip_set_name(), _zip_unchange(), and zip_delete().

◆ _zip_hash_free()

void _zip_hash_free ( zip_hash_t hash)

Definition at line 184 of file zip_hash.c.

184  {
185  zip_uint32_t i;
186 
187  if (hash == NULL) {
188  return;
189  }
190 
191  if (hash->table != NULL) {
192  for (i = 0; i < hash->table_size; i++) {
193  if (hash->table[i] != NULL) {
194  free_list(hash->table[i]);
195  }
196  }
197  free(hash->table);
198  }
199  free(hash);
200 }
lzma_index ** i
Definition: index.h:629
static void free_list(zip_hash_entry_t *entry)
Definition: zip_hash.c:68

References free(), free_list(), i, NULL, zip_hash::table, and zip_hash::table_size.

Referenced by zip_discard().

◆ _zip_hash_lookup()

zip_int64_t _zip_hash_lookup ( zip_hash_t hash,
const zip_uint8_t name,
zip_flags_t  flags,
zip_error_t error 
)

Definition at line 312 of file zip_hash.c.

312  {
313  zip_uint32_t hash_value, index;
315 
316  if (hash == NULL || name == NULL) {
318  return -1;
319  }
320 
321  if (hash->nentries > 0) {
322  hash_value = hash_string(name);
323  index = hash_value % hash->table_size;
324  for (entry = hash->table[index]; entry != NULL; entry = entry->next) {
325  if (strcmp((const char *)name, (const char *)entry->name) == 0) {
326  if (flags & ZIP_FL_UNCHANGED) {
327  if (entry->orig_index != -1) {
328  return entry->orig_index;
329  }
330  }
331  else {
332  if (entry->current_index != -1) {
333  return entry->current_index;
334  }
335  }
336  break;
337  }
338  }
339  }
340 
342  return -1;
343 }

References error(), flags, hash_string(), entry::name, zip_hash::nentries, NULL, zip_hash::table, zip_hash::table_size, ZIP_ER_INVAL, ZIP_ER_NOENT, zip_error_set(), and ZIP_FL_UNCHANGED.

Referenced by _zip_name_locate().

◆ _zip_hash_new()

zip_hash_t* _zip_hash_new ( zip_error_t error)

Definition at line 167 of file zip_hash.c.

167  {
168  zip_hash_t *hash;
169 
170  if ((hash = (zip_hash_t *)malloc(sizeof(zip_hash_t))) == NULL) {
172  return NULL;
173  }
174 
175  hash->table_size = 0;
176  hash->nentries = 0;
177  hash->table = NULL;
178 
179  return hash;
180 }

References error(), malloc(), zip_hash::nentries, NULL, zip_hash::table, zip_hash::table_size, ZIP_ER_MEMORY, and zip_error_set().

Referenced by _zip_new().

◆ _zip_hash_reserve_capacity()

bool _zip_hash_reserve_capacity ( zip_hash_t hash,
zip_uint64_t  capacity,
zip_error_t error 
)

Definition at line 347 of file zip_hash.c.

347  {
348  zip_uint32_t new_size;
349 
350  if (capacity == 0) {
351  return true;
352  }
353 
354  new_size = size_for_capacity(capacity);
355 
356  if (new_size <= hash->table_size) {
357  return true;
358  }
359 
360  if (!hash_resize(hash, new_size, error)) {
361  return false;
362  }
363 
364  return true;
365 }
static zip_uint32_t size_for_capacity(zip_uint64_t capacity)
Definition: zip_hash.c:136

References error(), hash_resize(), and size_for_capacity().

Referenced by _zip_open().

◆ _zip_hash_revert()

bool _zip_hash_revert ( zip_hash_t hash,
zip_error_t error 
)

Definition at line 369 of file zip_hash.c.

369  {
370  zip_uint32_t i;
371  zip_hash_entry_t *entry, *previous;
372 
373  for (i = 0; i < hash->table_size; i++) {
374  previous = NULL;
375  entry = hash->table[i];
376  while (entry) {
377  if (entry->orig_index == -1) {
379  if (previous) {
380  previous->next = entry->next;
381  }
382  else {
383  hash->table[i] = entry->next;
384  }
385  p = entry;
386  entry = entry->next;
387  /* previous does not change */
388  free(p);
389  hash->nentries--;
390  }
391  else {
392  entry->current_index = entry->orig_index;
393  previous = entry;
394  entry = entry->next;
395  }
396  }
397  }
398 
399  if (hash->nentries < hash->table_size * HASH_MIN_FILL && hash->table_size > HASH_MIN_SIZE) {
400  zip_uint32_t new_size = hash->table_size / 2;
401  while (hash->nentries < new_size * HASH_MIN_FILL && new_size > HASH_MIN_SIZE) {
402  new_size /= 2;
403  }
404  if (!hash_resize(hash, new_size, error)) {
405  return false;
406  }
407  }
408 
409  return true;
410 }
void * p
Definition: libc.cpp:67

References error(), free(), HASH_MIN_FILL, HASH_MIN_SIZE, hash_resize(), i, zip_hash::nentries, zip_hash_entry::next, NULL, p, zip_hash::table, and zip_hash::table_size.

Referenced by zip_unchange_all().

◆ free_list()

static void free_list ( zip_hash_entry_t entry)
static

Definition at line 68 of file zip_hash.c.

68  {
69  while (entry != NULL) {
70  zip_hash_entry_t *next = entry->next;
71  free(entry);
72  entry = next;
73  }
74 }

References free(), and NULL.

Referenced by _zip_hash_free().

◆ hash_resize()

static bool hash_resize ( zip_hash_t hash,
zip_uint32_t  new_size,
zip_error_t error 
)
static

Definition at line 97 of file zip_hash.c.

97  {
98  zip_hash_entry_t **new_table;
99 
100  if (new_size == hash->table_size) {
101  return true;
102  }
103 
104  if ((new_table = (zip_hash_entry_t **)calloc(new_size, sizeof(zip_hash_entry_t *))) == NULL) {
106  return false;
107  }
108 
109  if (hash->nentries > 0) {
110  zip_uint32_t i;
111 
112  for (i = 0; i < hash->table_size; i++) {
113  zip_hash_entry_t *entry = hash->table[i];
114  while (entry) {
115  zip_hash_entry_t *next = entry->next;
116 
117  zip_uint32_t new_index = entry->hash_value % new_size;
118 
119  entry->next = new_table[new_index];
120  new_table[new_index] = entry;
121 
122  entry = next;
123  }
124  }
125  }
126 
127  free(hash->table);
128  hash->table = new_table;
129  hash->table_size = new_size;
130 
131  return true;
132 }
void * calloc(size_t number, size_t size)
Definition: malloc.c:102

References calloc(), error(), free(), i, zip_hash::nentries, NULL, zip_hash::table, zip_hash::table_size, ZIP_ER_MEMORY, and zip_error_set().

Referenced by _zip_hash_add(), _zip_hash_delete(), _zip_hash_reserve_capacity(), and _zip_hash_revert().

◆ hash_string()

static zip_uint32_t hash_string ( const zip_uint8_t name)
static

Definition at line 79 of file zip_hash.c.

79  {
81 
82  if (name == NULL) {
83  return 0;
84  }
85 
86  while (*name != 0) {
87  value = (zip_uint64_t)(((value * HASH_MULTIPLIER) + (zip_uint8_t)*name) % 0x100000000ul);
88  name++;
89  }
90 
91  return (zip_uint32_t)value;
92 }
static int value
Definition: cmd_api.c:93
#define HASH_MULTIPLIER
Definition: zip_hash.c:39
#define HASH_START
Definition: zip_hash.c:40
uint64_t zip_uint64_t
Definition: zipconf.h:39
uint8_t zip_uint8_t
Definition: zipconf.h:33

References HASH_MULTIPLIER, HASH_START, NULL, and value.

Referenced by _zip_hash_add(), _zip_hash_delete(), and _zip_hash_lookup().

◆ size_for_capacity()

static zip_uint32_t size_for_capacity ( zip_uint64_t  capacity)
static

Definition at line 136 of file zip_hash.c.

136  {
137  double needed_size = capacity / HASH_MAX_FILL;
138  zip_uint32_t v;
139 
140  if (needed_size > ZIP_UINT32_MAX) {
141  v = ZIP_UINT32_MAX;
142  }
143  else {
144  v = (zip_uint32_t)needed_size;
145  }
146 
147  if (v > HASH_MAX_SIZE) {
148  return HASH_MAX_SIZE;
149  }
150 
151  /* From Bit Twiddling Hacks by Sean Eron Anderson <seander@cs.stanford.edu>
152  (http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2). */
153 
154  v--;
155  v |= v >> 1;
156  v |= v >> 2;
157  v |= v >> 4;
158  v |= v >> 8;
159  v |= v >> 16;
160  v++;
161 
162  return v;
163 }
const char * v
Definition: dsignal.c:12
#define ZIP_UINT32_MAX
Definition: zipconf.h:51

References HASH_MAX_FILL, HASH_MAX_SIZE, v, and ZIP_UINT32_MAX.

Referenced by _zip_hash_reserve_capacity().