RPA Toolkit
used types cleaned up... -4
[rpatk.git] / rlib / rharray.c
1 /*
2  *  Regular Pattern Analyzer (RPA)
3  *  Copyright (c) 2009-2010 Martin Stoilov
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  *  Martin Stoilov <martin@rpasearch.com>
19  */
20
21 #include "rlib/rharray.h"
22 #include "rlib/rstring.h"
23 #include "rlib/rmem.h"
24
25 /*
26  * Hash array
27  *
28  * names array:
29  * ----------------------------------------------
30  * | name1  | name2  | name3  |        | nameN  |
31  * ----------------------------------------------
32  *
33  * members array:
34  * ----------------------------------------------
35  * | memb1  | memb2  | memb3  |        | membN  |
36  * ----------------------------------------------
37  *
38  * Hash Entry:
39  * --------------------
40  * | pointer to name1  |
41  * --------------------
42  * | index of memb1    |
43  * --------------------
44  *
45  *
46  */
47
48
49
50 /*
51  * Copy the names in the hashed array.
52  * Pointers to the names are already in the array, but they point
53  * to the source array names. We duplicate these source names and
54  * replace the entries.
55  */
56 static void r_array_oncopy_rstr(rarray_t *array)
57 {
58         unsigned int index;
59         rstr_t *src, *dst;
60
61         for (index = 0; index < r_array_length(array); index++) {
62                 src = r_array_index(array, index, rstr_t*);
63                 if (src)
64                         dst = r_rstrdup(src->str, src->size);
65                 r_array_replace(array, index, &dst);
66         }
67 }
68
69 /*
70  * Destroy the names in the hashed array.
71  */
72 static void r_array_oncleanup_rstr(rarray_t *array)
73 {
74         unsigned int index;
75         rstr_t *src;
76
77         for (index = 0; index < r_array_length(array); index++) {
78                 src = r_array_index(array, index, rstr_t*);
79                 if (src)
80                         r_free(src);
81         }
82 }
83
84
85 robject_t *r_harray_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, unsigned int elt_size)
86 {
87         rharray_t *harray = (rharray_t*)obj;
88         r_object_init(obj, type, cleanup, copy);
89         harray->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
90         harray->members = r_carray_create(elt_size);
91         harray->names = r_array_create(sizeof(rstr_t*));
92         harray->names->oncleanup = r_array_oncleanup_rstr;
93         harray->names->oncopy = r_array_oncopy_rstr;
94         return obj;
95 }
96
97 rharray_t *r_harray_create(unsigned int elt_size)
98 {
99         rharray_t *harray;
100
101         harray = (rharray_t*)r_object_create(sizeof(*harray));
102         r_harray_init((robject_t*)harray, R_OBJECT_HARRAY,r_harray_cleanup, r_harray_copy, elt_size);
103         return harray;
104 }
105
106
107 void r_harray_destroy(rharray_t *array)
108 {
109         r_object_destroy((robject_t*)array);
110 }
111
112
113 robject_t *r_harray_copy(const robject_t *obj)
114 {
115         rharray_t *harray;
116         unsigned long i;
117         rstr_t *n;
118         const rharray_t *src = (const rharray_t *)obj;
119
120         harray = (rharray_t*)r_object_create(sizeof(*harray));
121         r_object_init(&harray->obj, R_OBJECT_HARRAY, r_harray_cleanup, r_harray_copy);
122         harray->names = (rarray_t*)r_array_copy((robject_t*)src->names);
123         harray->members = (rcarray_t*)r_carray_copy((robject_t*)src->members);
124         harray->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
125         for (i = 0; i < r_carray_length(src->members); i++) {
126                 n = r_array_index(harray->names, i, rstr_t*);
127                 r_hash_insert_indexval(harray->hash, (rconstpointer)n, i);
128         }
129         return (robject_t*)harray;
130 }
131
132
133 void r_harray_cleanup(robject_t *obj)
134 {
135         rharray_t *harray = (rharray_t *)obj;
136         r_object_destroy((robject_t*)harray->members);
137         r_object_destroy((robject_t*)harray->names);
138         r_object_destroy((robject_t*)harray->hash);
139         r_object_cleanup(&harray->obj);
140 }
141
142
143 long r_harray_add(rharray_t *harray, const char *name, unsigned int namesize, rconstpointer pval)
144 {
145         rstr_t *membrName;
146         long index, nameindex;
147
148         membrName = r_rstrdup(name, namesize);
149         index = r_carray_add(harray->members, pval);
150         nameindex = r_array_add(harray->names, &membrName);
151         /*
152          * Lets try to keep the name index and the data index in sync,
153          * if they are not, that might be a problem - we will have to
154          * think of some sort reverse lookup mechanism.
155          */
156         R_ASSERT(index == nameindex);
157         r_hash_insert_indexval(harray->hash, (rconstpointer)membrName, index);
158         return index;
159 }
160
161
162 long r_harray_add_s(rharray_t *harray, const char *name, rconstpointer pval)
163 {
164         return r_harray_add(harray, name, r_strlen(name), pval);
165 }
166
167
168 long r_harray_replace(rharray_t *harray, const char *name, unsigned int namesize, rconstpointer pval)
169 {
170         long index = r_harray_lookup(harray, name, namesize);
171
172         if (index < 0)
173                 return r_harray_add(harray, name, namesize, pval);
174         index = r_carray_replace(harray->members, index,  pval);
175         return index;
176 }
177
178 long r_harray_replace_s(rharray_t *harray, const char *name, rconstpointer pval)
179 {
180         return r_harray_replace(harray, name, r_strlen(name), pval);
181 }
182
183
184 long r_harray_lookup(rharray_t *harray, const char *name, unsigned int namesize)
185 {
186         rsize_t found;
187
188         rstr_t lookupstr = {(char*)name, namesize};
189         found = r_hash_lookup_indexval(harray->hash, &lookupstr);
190         if (found == R_HASH_INVALID_INDEXVAL)
191                 return -1;
192         return (long)found;
193 }
194
195
196 long r_harray_lookup_s(rharray_t *harray, const char *name)
197 {
198         return r_harray_lookup(harray, name, r_strlen(name));
199 }
200
201
202 long r_harray_taillookup(rharray_t *harray, const char *name, unsigned int namesize)
203 {
204         rsize_t found;
205
206         rstr_t lookupstr = {(char*)name, namesize};
207         found = r_hash_taillookup_indexval(harray->hash, &lookupstr);
208         if (found == R_HASH_INVALID_INDEXVAL)
209                 return -1;
210         return (long)found;
211 }
212
213
214 long r_harray_taillookup_s(rharray_t *harray, const char *name)
215 {
216         return r_harray_lookup(harray, name, r_strlen(name));
217 }
218
219
220
221 rhash_node_t* r_harray_nodelookup(rharray_t *harray, rhash_node_t *cur, const char *name, unsigned int namesize)
222 {
223         rstr_t lookupstr = {(char*)name, namesize};
224         return r_hash_nodelookup(harray->hash, cur, &lookupstr);
225 }
226
227
228 rhash_node_t* r_harray_nodelookup_s(rharray_t *harray, rhash_node_t *cur, const char *name)
229 {
230         return r_harray_nodelookup(harray, cur, name, r_strlen(name));
231 }
232
233
234 rhash_node_t* r_harray_nodetaillookup(rharray_t *harray, rhash_node_t *cur, const char *name, unsigned int namesize)
235 {
236         rstr_t lookupstr = {(char*)name, namesize};
237         return r_hash_nodetaillookup(harray->hash, cur, &lookupstr);
238 }
239
240
241 rhash_node_t* r_harray_nodetaillookup_s(rharray_t *harray, rhash_node_t *cur, const char *name)
242 {
243         return r_harray_nodetaillookup(harray, cur, name, r_strlen(name));
244 }
245
246
247 int r_harray_set(rharray_t *harray, long index, rconstpointer pval)
248 {
249         if (index < 0)
250                 return -1;
251         r_carray_replace(harray->members, index, pval);
252         return 0;
253 }
254
255
256 rpointer r_harray_get(rharray_t *harray, rsize_t index)
257 {
258         if (index >= r_carray_length(harray->members) || index < 0)
259                 return NULL;
260         return r_carray_slot(harray->members, index);
261 }
262
263