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