2 * Regular Pattern Analyzer (RPA)
3 * Copyright (c) 2009-2010 Martin Stoilov
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.
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.
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/>.
18 * Martin Stoilov <martin@rpasearch.com>
21 #include "rlib/rharray.h"
22 #include "rlib/rstring.h"
23 #include "rlib/rmem.h"
29 * ----------------------------------------------
30 * | name1 | name2 | name3 | | nameN |
31 * ----------------------------------------------
34 * ----------------------------------------------
35 * | memb1 | memb2 | memb3 | | membN |
36 * ----------------------------------------------
39 * --------------------
40 * | pointer to name1 |
41 * --------------------
43 * --------------------
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.
56 static void r_array_oncopy_rstr(rarray_t *array)
61 for (index = 0; index < r_array_length(array); index++) {
62 src = r_array_index(array, index, rstr_t*);
64 dst = r_rstrdup(src->str, src->size);
65 r_array_replace(array, index, &dst);
70 * Destroy the names in the hashed array.
72 static void r_array_oncleanup_rstr(rarray_t *array)
77 for (index = 0; index < r_array_length(array); index++) {
78 src = r_array_index(array, index, rstr_t*);
85 robject_t *r_harray_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, unsigned int elt_size)
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;
97 rharray_t *r_harray_create(unsigned int elt_size)
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);
107 void r_harray_destroy(rharray_t *array)
109 r_object_destroy((robject_t*)array);
113 robject_t *r_harray_copy(const robject_t *obj)
118 const rharray_t *src = (const rharray_t *)obj;
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);
129 return (robject_t*)harray;
133 void r_harray_cleanup(robject_t *obj)
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);
143 long r_harray_add(rharray_t *harray, const char *name, rsize_t namesize, rconstpointer pval)
146 long index, nameindex;
148 membrName = r_rstrdup(name, namesize);
149 index = r_carray_add(harray->members, pval);
150 nameindex = r_array_add(harray->names, &membrName);
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.
156 R_ASSERT(index == nameindex);
157 r_hash_insert_indexval(harray->hash, (rconstpointer)membrName, index);
162 long r_harray_add_s(rharray_t *harray, const char *name, rconstpointer pval)
164 return r_harray_add(harray, name, r_strlen(name), pval);
168 long r_harray_replace(rharray_t *harray, const char *name, rsize_t namesize, rconstpointer pval)
170 long index = r_harray_lookup(harray, name, namesize);
173 return r_harray_add(harray, name, namesize, pval);
174 index = r_carray_replace(harray->members, index, pval);
178 long r_harray_replace_s(rharray_t *harray, const char *name, rconstpointer pval)
180 return r_harray_replace(harray, name, r_strlen(name), pval);
184 long r_harray_lookup(rharray_t *harray, const char *name, rsize_t namesize)
188 rstr_t lookupstr = {(char*)name, namesize};
189 found = r_hash_lookup_indexval(harray->hash, &lookupstr);
190 if (found == R_HASH_INVALID_INDEXVAL)
196 long r_harray_lookup_s(rharray_t *harray, const char *name)
198 return r_harray_lookup(harray, name, r_strlen(name));
202 long r_harray_taillookup(rharray_t *harray, const char *name, rsize_t namesize)
206 rstr_t lookupstr = {(char*)name, namesize};
207 found = r_hash_taillookup_indexval(harray->hash, &lookupstr);
208 if (found == R_HASH_INVALID_INDEXVAL)
214 long r_harray_taillookup_s(rharray_t *harray, const char *name)
216 return r_harray_lookup(harray, name, r_strlen(name));
221 rhash_node_t* r_harray_nodelookup(rharray_t *harray, rhash_node_t *cur, const char *name, rsize_t namesize)
223 rstr_t lookupstr = {(char*)name, namesize};
224 return r_hash_nodelookup(harray->hash, cur, &lookupstr);
228 rhash_node_t* r_harray_nodelookup_s(rharray_t *harray, rhash_node_t *cur, const char *name)
230 return r_harray_nodelookup(harray, cur, name, r_strlen(name));
234 rhash_node_t* r_harray_nodetaillookup(rharray_t *harray, rhash_node_t *cur, const char *name, rsize_t namesize)
236 rstr_t lookupstr = {(char*)name, namesize};
237 return r_hash_nodetaillookup(harray->hash, cur, &lookupstr);
241 rhash_node_t* r_harray_nodetaillookup_s(rharray_t *harray, rhash_node_t *cur, const char *name)
243 return r_harray_nodetaillookup(harray, cur, name, r_strlen(name));
247 int r_harray_set(rharray_t *harray, long index, rconstpointer pval)
251 r_carray_replace(harray->members, index, pval);
256 rpointer r_harray_get(rharray_t *harray, rsize_t index)
258 if (index >= r_carray_length(harray->members) || index < 0)
260 return r_carray_slot(harray->members, index);