Delta Chat Core C-API
dc_hash.h
1 #ifndef __DC_HASH_H__
2 #define __DC_HASH_H__
3 #ifdef __cplusplus
4 extern "C"
5 {
6 #endif
7 
8 
9 /* Forward declarations of structures.
10  */
11 typedef struct _dc_hash dc_hash_t;
12 typedef struct _dc_hashelem dc_hashelem_t;
13 
14 
15 /* A complete hash table is an instance of the following structure.
16  * The internals of this structure are intended to be opaque -- client
17  * code should not attempt to access or modify the fields of this structure
18  * directly. Change this structure only by using the routines below.
19  * However, many of the "procedures" and "functions" for modifying and
20  * accessing this structure are really macros, so we can't really make
21  * this structure opaque.
22  */
23 struct _dc_hash
24 {
25  char keyClass; /* SJHASH_INT, _POINTER, _STRING, _BINARY */
26  char copyKey; /* True if copy of key made on insert */
27  int count; /* Number of entries in this table */
28  dc_hashelem_t *first; /* The first element of the array */
29  int htsize; /* Number of buckets in the hash table */
30  struct _ht
31  { /* the hash table */
32  int count; /* Number of entries with this hash */
33  dc_hashelem_t *chain; /* Pointer to first entry with this hash */
34  } *ht;
35 };
36 
37 
38 /* Each element in the hash table is an instance of the following
39  * structure. All elements are stored on a single doubly-linked list.
40  *
41  * Again, this structure is intended to be opaque, but it can't really
42  * be opaque because it is used by macros.
43  */
44 struct _dc_hashelem
45 {
46  dc_hashelem_t *next, *prev; /* Next and previous elements in the table */
47  void* data; /* Data associated with this element */
48  void* pKey; /* Key associated with this element */
49  int nKey; /* Key associated with this element */
50 };
51 
52 
53 /*
54  * There are 4 different modes of operation for a hash table:
55  *
56  * DC_HASH_INT nKey is used as the key and pKey is ignored.
57  *
58  * DC_HASH_POINTER pKey is used as the key and nKey is ignored.
59  *
60  * DC_HASH_STRING pKey points to a string that is nKey bytes long
61  * (including the null-terminator, if any). Case
62  * is ignored in comparisons.
63  *
64  * DC_HASH_BINARY pKey points to binary data nKey bytes long.
65  * memcmp() is used to compare keys.
66  *
67  * A copy of the key is made for DC_HASH_STRING and DC_HASH_BINARY
68  * if the copyKey parameter to dc_hash_init() is 1.
69  */
70 #define DC_HASH_INT 1
71 #define DC_HASH_POINTER 2
72 #define DC_HASH_STRING 3
73 #define DC_HASH_BINARY 4
74 
75 
76 /*
77  * Just to make the last parameter of dc_hash_init() more readable.
78  */
79 #define DC_HASH_COPY_KEY 1
80 
81 
82 /*
83  * Access routines. To delete an element, insert a NULL pointer.
84  */
85 void dc_hash_init (dc_hash_t*, int keytype, int copyKey);
86 void* dc_hash_insert (dc_hash_t*, const void *pKey, int nKey, void *pData);
87 void* dc_hash_find (const dc_hash_t*, const void *pKey, int nKey);
88 void dc_hash_clear (dc_hash_t*);
89 
90 #define dc_hash_find_str(H, s) dc_hash_find((H), (s), strlen((s)))
91 #define dc_hash_insert_str(H, s, d) dc_hash_insert((H), (s), strlen((s)), (d))
92 
93 
94 /*
95  * Macros for looping over all elements of a hash table. The idiom is
96  * like this:
97  *
98  * SjHash h;
99  * SjHashElem *p;
100  * ...
101  * for(p=dc_hash_first(&h); p; p=dc_hash_next(p)){
102  * SomeStructure *pData = dc_hash_data(p);
103  * // do something with pData
104  * }
105  */
106 #define dc_hash_first(H) ((H)->first)
107 #define dc_hash_next(E) ((E)->next)
108 #define dc_hash_data(E) ((E)->data)
109 #define dc_hash_key(E) ((E)->pKey)
110 #define dc_hash_keysize(E) ((E)->nKey)
111 
112 
113 /*
114  * Number of entries in a hash table
115  */
116 #define dc_hash_cnt(H) ((H)->count)
117 
118 
119 #ifdef __cplusplus
120 }; /* /extern "C" */
121 #endif
122 #endif /* __DC_HASH_H__ */