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