RPA Toolkit
work on AST
[rpatk.git] / rlib / rharray.c
1 #include "rharray.h"
2 #include "rstring.h"
3 #include "rmem.h"
4
5 /*
6  * Hash array
7  *
8  * names array:
9  * ----------------------------------------------
10  * | name1  | name2  | name3  |        | nameN  |
11  * ----------------------------------------------
12  *
13  * members array:
14  * ----------------------------------------------
15  * | memb1  | memb2  | memb3  |        | membN  |
16  * ----------------------------------------------
17  *
18  * Hash Entry:
19  * --------------------
20  * | pointer to name1  |
21  * --------------------
22  * | index of memb1    |
23  * --------------------
24  *
25  *
26  */
27
28
29
30 /*
31  * Copy the names in the hashed array.
32  * Pointers to the names are already in the array, but they point
33  * to the source array names. We duplicate these source names and
34  * replace the entries.
35  */
36 static void r_array_oncopy_rstr(rarray_t *array)
37 {
38         ruint index;
39         rstr_t *src, *dst;
40
41         for (index = 0; index < r_array_length(array); index++) {
42                 src = r_array_index(array, index, rstr_t*);
43                 if (src)
44                         dst = r_rstrdup(src->str, src->size);
45                 r_array_replace(array, index, &dst);
46         }
47 }
48
49 /*
50  * Destroy the names in the hashed array.
51  */
52 static void r_array_oncleanup_rstr(rarray_t *array)
53 {
54         ruint index;
55         rstr_t *src;
56
57         for (index = 0; index < r_array_length(array); index++) {
58                 src = r_array_index(array, index, rstr_t*);
59                 if (src)
60                         r_free(src);
61         }
62 }
63
64
65 robject_t *r_harray_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint elt_size)
66 {
67         rharray_t *harray = (rharray_t*)obj;
68         r_object_init(obj, type, cleanup, copy);
69         harray->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
70         harray->members = r_carray_create(elt_size);
71         harray->names = r_array_create(sizeof(rstr_t*));
72         harray->names->oncleanup = r_array_oncleanup_rstr;
73         harray->names->oncopy = r_array_oncopy_rstr;
74         return obj;
75 }
76
77 rharray_t *r_harray_create(ruint elt_size)
78 {
79         rharray_t *harray;
80
81         harray = (rharray_t*)r_object_create(sizeof(*harray));
82         r_harray_init((robject_t*)harray, R_OBJECT_HARRAY,r_harray_cleanup, r_harray_copy, elt_size);
83         return harray;
84 }
85
86
87 robject_t *r_harray_copy(const robject_t *obj)
88 {
89         rharray_t *harray;
90         int i;
91         rstr_t *n;
92         const rharray_t *src = (const rharray_t *)obj;
93
94         harray = (rharray_t*)r_object_create(sizeof(*harray));
95         r_object_init(&harray->obj, R_OBJECT_HARRAY, r_harray_cleanup, r_harray_copy);
96         harray->names = (rarray_t*)r_array_copy((robject_t*)src->names);
97         harray->members = (rcarray_t*)r_carray_copy((robject_t*)src->members);
98         harray->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
99         for (i = 0; i < r_carray_length(src->members); i++) {
100                 n = r_array_index(harray->names, i, rstr_t*);
101                 r_hash_insert_indexval(harray->hash, (rconstpointer)n, i);
102         }
103         return (robject_t*)harray;
104 }
105
106
107 void r_harray_cleanup(robject_t *obj)
108 {
109         rharray_t *harray = (rharray_t *)obj;
110         r_object_destroy((robject_t*)harray->members);
111         r_object_destroy((robject_t*)harray->names);
112         r_object_destroy((robject_t*)harray->hash);
113         r_object_cleanup(&harray->obj);
114 }
115
116
117 rlong r_harray_add(rharray_t *harray, const rchar *name, ruint namesize, rconstpointer pval)
118 {
119         rstr_t *membrName;
120         rlong index;
121
122         membrName = r_rstrdup(name, namesize);
123         index = r_carray_add(harray->members, pval);
124         r_array_add(harray->names, &membrName);
125         r_hash_insert_indexval(harray->hash, (rconstpointer)membrName, index);
126         return index;
127 }
128
129
130 rlong r_harray_add_s(rharray_t *harray, const rchar *name, rconstpointer pval)
131 {
132         return r_harray_add(harray, name, r_strlen(name), pval);
133 }
134
135
136 rlong r_harray_replace(rharray_t *harray, const rchar *name, ruint namesize, rconstpointer pval)
137 {
138         rlong index = r_harray_lookup(harray, name, namesize);
139
140         if (index < 0)
141                 return r_harray_add(harray, name, namesize, pval);
142         index = r_carray_replace(harray->members, index,  pval);
143         return index;
144 }
145
146 rlong r_harray_replace_s(rharray_t *harray, const rchar *name, rconstpointer pval)
147 {
148         return r_harray_replace(harray, name, r_strlen(name), pval);
149 }
150
151
152 rlong r_harray_lookup(rharray_t *harray, const rchar *name, ruint namesize)
153 {
154         rulong found;
155
156         rstr_t lookupstr = {(char*)name, namesize};
157         found = r_hash_lookup_indexval(harray->hash, &lookupstr);
158         if (found == R_HASH_INVALID_INDEXVAL)
159                 return -1;
160         return (rlong)found;
161 }
162
163
164 rlong r_harray_lookup_s(rharray_t *harray, const rchar *name)
165 {
166         return r_harray_lookup(harray, name, r_strlen(name));
167 }
168
169
170 rlong r_harray_taillookup(rharray_t *harray, const rchar *name, ruint namesize)
171 {
172         rulong found;
173
174         rstr_t lookupstr = {(char*)name, namesize};
175         found = r_hash_taillookup_indexval(harray->hash, &lookupstr);
176         if (found == R_HASH_INVALID_INDEXVAL)
177                 return -1;
178         return (rlong)found;
179 }
180
181
182 rlong r_harray_taillookup_s(rharray_t *harray, const rchar *name)
183 {
184         return r_harray_lookup(harray, name, r_strlen(name));
185 }
186
187
188
189 rhash_node_t* r_harray_nodelookup(rharray_t *harray, rhash_node_t *cur, const rchar *name, ruint namesize)
190 {
191         rstr_t lookupstr = {(char*)name, namesize};
192         return r_hash_nodelookup(harray->hash, cur, &lookupstr);
193 }
194
195
196 rhash_node_t* r_harray_nodelookup_s(rharray_t *harray, rhash_node_t *cur, const rchar *name)
197 {
198         return r_harray_nodelookup(harray, cur, name, r_strlen(name));
199 }
200
201
202 rhash_node_t* r_harray_nodetaillookup(rharray_t *harray, rhash_node_t *cur, const rchar *name, ruint namesize)
203 {
204         rstr_t lookupstr = {(char*)name, namesize};
205         return r_hash_nodetaillookup(harray->hash, cur, &lookupstr);
206 }
207
208
209 rhash_node_t* r_harray_nodetaillookup_s(rharray_t *harray, rhash_node_t *cur, const rchar *name)
210 {
211         return r_harray_nodetaillookup(harray, cur, name, r_strlen(name));
212 }
213
214
215 rint r_harray_set(rharray_t *harray, rlong index, rconstpointer pval)
216 {
217         if (index < 0)
218                 return -1;
219         r_carray_replace(harray->members, index, pval);
220         return 0;
221 }
222
223
224 rpointer r_harray_get(rharray_t *harray, rulong index)
225 {
226         if (index >= r_carray_length(harray->members) || index < 0)
227                 return NULL;
228         return r_carray_slot(harray->members, index);
229 }
230
231