]> mj.ucw.cz Git - libucw.git/blob - lib/object.c
Added tests for the hash table module.
[libucw.git] / lib / object.c
1 /*
2  *      Sherlock Library -- Object Functions
3  *
4  *      (c) 1997--2004 Martin Mares <mj@ucw.cz>
5  *      (c) 2004 Robert Spalek <robert@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #include "lib/lib.h"
12 #include "lib/mempool.h"
13 #include "lib/fastbuf.h"
14 #include "lib/object.h"
15
16 #include <string.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19
20 void
21 obj_dump(struct odes *o)
22 {
23   for(struct oattr *a=o->attrs; a; a=a->next)
24     for(struct oattr *b=a; b; b=b->same)
25       printf("%c%s\n", (a==b ? a->attr : ' '), b->val);
26 }
27
28 static struct oattr *
29 oa_new(struct odes *o, uns x, byte *v)
30 {
31   struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr) + strlen(v)+1);
32
33   a->next = a->same = NULL;
34   a->attr = x;
35   a->val = (byte*) (a+1);
36   strcpy(a->val, v);
37   return a;
38 }
39
40 static struct oattr *
41 oa_new_ref(struct odes *o, uns x, byte *v)
42 {
43   struct oattr *a = mp_alloc(o->pool, sizeof(struct oattr));
44
45   a->next = a->same = NULL;
46   a->attr = x;
47   a->val = v;
48   return a;
49 }
50
51 struct odes *
52 obj_new(struct mempool *pool)
53 {
54   struct odes *o = mp_alloc(pool, sizeof(struct odes));
55   o->pool = pool;
56   o->attrs = NULL;
57   o->cached_attr = NULL;
58   return o;
59 }
60
61 struct oattr *
62 obj_find_attr(struct odes *o, uns x)
63 {
64   struct oattr *a;
65   for(a=o->attrs; a && a->attr != x; a=a->next)
66     ;
67   return a;
68 }
69
70 struct oattr *
71 obj_find_attr_last(struct odes *o, uns x)
72 {
73   struct oattr *a = obj_find_attr(o, x);
74
75   if (a)
76     {
77       while (a->same)
78         a = a->same;
79     }
80   return a;
81 }
82
83 uns
84 obj_del_attr(struct odes *o, struct oattr *a)
85 {
86   struct oattr *x, **p, *y, *l;
87   byte aa = a->attr;
88
89   o->cached_attr = NULL;
90   p = &o->attrs;
91   while (x = *p)
92     {
93       if (x->attr == aa)
94         {
95           y = x;
96           l = NULL;
97           while (x = *p)
98             {
99               if (x == a)
100                 {
101                   *p = x->same;
102                   return 1;
103                 }
104               p = &x->same;
105               l = x;
106             }
107           return 0;
108         }
109       p = &x->next;
110     }
111   return 0;
112 }
113
114 byte *
115 obj_find_aval(struct odes *o, uns x)
116 {
117   struct oattr *a = obj_find_attr(o, x);
118   return a ? a->val : NULL;
119 }
120
121 uns
122 obj_find_anum(struct odes *o, uns x, uns def)
123 {
124   struct oattr *a = obj_find_attr(o, x);
125   return a ? (uns)atol(a->val) : def;
126 }
127
128 struct oattr *
129 obj_set_attr(struct odes *o, uns x, byte *v)
130 {
131   struct oattr *a, **z;
132
133   z = &o->attrs;
134   while (a = *z)
135     {
136       if (a->attr == x)
137         {
138           *z = a->next;
139           goto set;
140         }
141       z = &a->next;
142     }
143
144  set:
145   if (v)
146     {
147       a = oa_new(o, x, v);
148       a->next = o->attrs;
149       o->attrs = a;
150     }
151   else
152     a = NULL;
153   o->cached_attr = a;
154   return a;
155 }
156
157 struct oattr *
158 obj_set_attr_num(struct odes *o, uns a, uns v)
159 {
160   byte x[32];
161
162   sprintf(x, "%d", v);
163   return obj_set_attr(o, a, x);
164 }
165
166 static inline struct oattr *
167 obj_add_attr_internal(struct odes *o, struct oattr *b)
168 {
169   struct oattr *a, **z;
170
171   if (!(a = o->cached_attr) || a->attr != b->attr)
172     {
173       z = &o->attrs;
174       while ((a = *z) && a->attr != b->attr)
175         z = &a->next;
176       if (!a)
177         {
178           *z = b;
179           /* b->next is NULL */
180           goto done;
181         }
182     }
183   while (a->same)
184     a = a->same;
185   a->same = b;
186  done:
187   o->cached_attr = b;
188   return b;
189 }
190
191 struct oattr *
192 obj_add_attr(struct odes *o, uns x, byte *v)
193 {
194   return obj_add_attr_internal(o, oa_new(o, x, v));
195 }
196
197 struct oattr *
198 obj_add_attr_ref(struct odes *o, uns x, byte *v)
199 {
200   return obj_add_attr_internal(o, oa_new_ref(o, x, v));
201 }
202
203 struct oattr *
204 obj_prepend_attr(struct odes *o, uns x, byte *v)
205 {
206   struct oattr *a, *b, **z;
207
208   b = oa_new(o, x, v);
209   z = &o->attrs;
210   while (a = *z)
211     {
212       if (a->attr == x)
213         {
214           b->same = a;
215           b->next = a->next;
216           a->next = NULL;
217           *z = b;
218           return b;
219         }
220       z = &a->next;
221     }
222   b->next = o->attrs;
223   o->attrs = b;
224   return b;
225 }
226
227 struct oattr *
228 obj_insert_attr(struct odes *o, struct oattr *first, struct oattr *after, byte *v)
229 {
230   struct oattr *b = oa_new(o, first->attr, v);
231   b->same = after->same;
232   after->same = b;
233   return b;
234 }
235
236 void
237 obj_move_attr_to_head(struct odes *o, uns x)
238 {
239   struct oattr *a, **z;
240
241   z = &o->attrs;
242   while (a = *z)
243     {
244       if (a->attr == x)
245         {
246           *z = a->next;
247           a->next = o->attrs;
248           o->attrs = a;
249           break;
250         }
251       z = &a->next;
252     }
253 }
254
255 void
256 obj_move_attr_to_tail(struct odes *o, uns x)
257 {
258   struct oattr *a, **z;
259
260   z = &o->attrs;
261   while (a = *z)
262     {
263       if (a->attr == x)
264         {
265           *z = a->next;
266           while (*z)
267             z = &(*z)->next;
268           *z = a;
269           a->next = NULL;
270           break;
271         }
272       z = &a->next;
273     }
274 }