1 /*
2 LICENSE INFORMATION:
3 This program is free software; you can redistribute it and/or
4 modify it under the terms of the GNU General Public
5 License as published by the Free Software Foundation; either
6 version 2 of the License, or (at your option) any later version.
7 
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 General Public License for more details.
12 
13 You should have received a copy of the GNU General Public
14 License along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 Copyright (c) 2002 Bruno T. C. de Oliveira
17 
18 INFORMA��ES DE LICEN�A:
19 Este programa � um software de livre distribui��o; voc� pode
20 redistribu�-lo e/ou modific�-lo sob os termos da GNU General
21 Public License, conforme publicado pela Free Software Foundation,
22 pela vers�o 2 da licen�a ou qualquer vers�o posterior.
23 
24 Este programa � distribu�do na esperan�a de que ele ser� �til
25 aos seus usu�rios, por�m, SEM QUAISQUER GARANTIAS; sem sequer
26 a garantia impl�cita de COMERCIABILIDADE ou DE ADEQUA��O A
27 QUALQUER FINALIDADE ESPEC�FICA. Consulte a GNU General Public
28 License para obter mais detalhes (uma c�pia acompanha este
29 programa, armazenada no arquivo COPYING).
30 */
31 
32 /* hashdict.h
33  * A general purpose dictionary implemented by means of a hashtable.
34  * This dictionary maps string keys to values of arbitrary type.
35  * It allows the specification of a value-destroy function that will
36  * be called whenever values are to be overwritten or deleted.
37  *
38  * Restrictions:
39  *
40  * - keys must be strings of positive length, and must of course be
41  * unique.
42  *
43  * - values may not be NULL, because NULL is used as a
44  * return value to indicate absense of keys, and because when writing/reading
45  * to a file handling of NULL values would complicate things.
46  *
47  * Copyright (c) 2003 by Bruno T. C. de Oliveira
48  * All rights reserved.
49  *
50  * 2003.01.07
51  */
52 
53 #ifndef btco_bores_hashdict_h
54 #define btco_bores_hashdict_h
55 
56 #include <stdio.h>
57 #include <stdbool.h>
58 
59 /* opaque dictionary handle */
60 struct HashDict_;
61 typedef struct HashDict_ HashDict;
62 
63 /* iterator type */
64 struct HashDictIt_ {
65    /* indicates whether this iterator is past the end of the dictionary */
66    bool pastend;
67 
68    /* key and value of entry iterator is currently pointing to. Read only. */
69    const char *key;
70    const void *value;
71 
72    /* internal data. Do not tamper with. */
73    HashDict* dict;  /* the dictionary this iterator pertains to */
74    int nextbucket;  /* the next bucket to be visited after this one ends */
75    void *nextnode;  /* the next node in this bucket to be visited. If
76                        NULL, next advancement will cause the iterator
77                        to go to the next nonempty bucket */
78 };
79 typedef struct HashDictIt_ HashDictIt;
80 
81 /* Creates a new dictionary with default bucketcount and no value destroyer
82  * function. */
83 HashDict* hashdict_create(void);
84 
85 /* Creates a new dictionary given bucketcount and a value destroyer function.*/
86 HashDict* hashdict_create_ex(int bucketcount, void (*valuedestroyer)(void*));
87 
88 /* Destroy a dictionary previously created by hashdict_create */
89 void hashdict_destroy(HashDict* hd);
90 
91 /* Look up key <key> in the dictionary. Returns the associated value,
92  * or NULL if the value is not found. */
93 void* hashdict_get(HashDict* hd, const char *key);
94 
95 /* Sets the value associated to the given key. If the key already exists,
96  * the value associated to it will be overwritten (and the value-
97  * destroyer function will be called); otherwise, a new entry will be added.
98  *
99  * As a convenience, if value is NULL, this function is equivalent
100  * to hashdict_unset(hd, key) */
101 void hashdict_set(HashDict* hd, const char *key, const void *value);
102 
103 /* Removes from the dictionary the entry whose key is <key>, if it exists.
104  * If it was removed, returns true; if it was not found, returns false */
105 bool hashdict_unset(HashDict* hd, const char *key);
106 
107 /* Writes dictionary to file f in a binary format. valuewriter is a
108  * function that will be used to write the values onto the stream. */
109 void hashdict_write(HashDict *hd, FILE *f, void (*valuewriter)(void*, FILE*));
110 
111 /* Reads a dictionary previously saved with hashdict_write.
112  * valuereader is a function that will be used to read values from
113  * the stream. If valuereader returns NULL at any time, this
114  * function will interpret it as an error. If this happens,
115  * or if any other error occurs, this function will return NULL. */
116 HashDict* hashdict_read(HashDict *hd, FILE *f, void* (*valuereader)(FILE*));
117 
118 /* Returns a new hash dict iterator that points BEFORE the first entry
119  * in the dictionary. Iterators are lightweight objects, i.e.,
120  * they don't need to be deallocated. That's why there is no
121  * hashdict_it_destroy function.
122  *
123  * Please note that the iterator returned is not in a valid position
124  * (it is BEFORE the start). You must advance it before using the value.
125  * This behavior is useful because you can write neat loops:
126  *
127  *    it = hashdict_it_start(hd);
128  *    while (hashdict_it_advance(it)) {
129  *        // use it->key and it->value here
130  *    }
131  */
132 HashDictIt hashdict_it_start(HashDict *hd);
133 
134 /* Advances the given iterator. Returns true if advancement was successful,
135  * or false if the end of the dictionary was reached. */
136 bool hashdict_it_advance(HashDictIt *hdi);
137 
138 #endif
139 
140