]> mj.ucw.cz Git - libucw.git/blob - lib/object.c
6091d1d75ed20edcfdea7ac8f6b828026263b3bf
[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;
162
163   if (!(a = o->cached_attr) || a->attr != b->attr)
164     {
165       if (!(a = obj_find_attr(o, b->attr)))
166         {
167           b->next = o->attrs;
168           o->attrs = b;
169           goto done;
170         }
171     }
172   while (a->same)
173     a = a->same;
174   a->same = b;
175  done:
176   o->cached_attr = b;
177   return b;
178 }
179
180 struct oattr *
181 obj_add_attr(struct odes *o, uns x, byte *v)
182 {
183   return obj_add_attr_internal(o, oa_new(o, x, v));
184 }
185
186 struct oattr *
187 obj_add_attr_ref(struct odes *o, uns x, byte *v)
188 {
189   return obj_add_attr_internal(o, oa_new_ref(o, x, v));
190 }
191
192 struct oattr *
193 obj_prepend_attr(struct odes *o, uns x, byte *v)
194 {
195   struct oattr *a, *b, **z;
196
197   b = oa_new(o, x, v);
198   z = &o->attrs;
199   while (a = *z)
200     {
201       if (a->attr == x)
202         {
203           b->same = a;
204           b->next = a->next;
205           a->next = NULL;
206           *z = b;
207           return b;
208         }
209       z = &a->next;
210     }
211   b->next = o->attrs;
212   o->attrs = b;
213   return b;
214 }
215
216 struct oattr *
217 obj_insert_attr(struct odes *o, struct oattr *first, struct oattr *after, byte *v)
218 {
219   struct oattr *b = oa_new(o, first->attr, v);
220   b->same = after->same;
221   after->same = b;
222   return b;
223 }
224
225 void
226 obj_move_attr_to_head(struct odes *o, uns x)
227 {
228   struct oattr *a, **z;
229
230   z = &o->attrs;
231   while (a = *z)
232     {
233       if (a->attr == x)
234         {
235           *z = a->next;
236           a->next = o->attrs;
237           o->attrs = a;
238           break;
239         }
240       z = &a->next;
241     }
242 }
243
244 void
245 obj_move_attr_to_tail(struct odes *o, uns x)
246 {
247   struct oattr *a, **z;
248
249   z = &o->attrs;
250   while (a = *z)
251     {
252       if (a->attr == x)
253         {
254           *z = a->next;
255           while (*z)
256             z = &(*z)->next;
257           *z = a;
258           a->next = NULL;
259           break;
260         }
261       z = &a->next;
262     }
263 }