]> mj.ucw.cz Git - libucw.git/blob - lib/object.c
db471c4b0257e25d58e61e4ce9ec6bb9f1879eae
[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_read_multi(struct fastbuf *f, struct odes *o)
63 {
64   /* Read a multi-part object ending with either EOF or a NUL character */
65   byte buf[MAX_ATTR_SIZE];
66   while (bpeekc(f) > 0 && bgets(f, buf, sizeof(buf)))
67     if (buf[0])
68       obj_add_attr(o, buf[0], buf+1);
69 }
70
71 void
72 obj_write(struct fastbuf *f, struct odes *d)
73 {
74   for(struct oattr *a=d->attrs; a; a=a->next)
75     for(struct oattr *b=a; b; b=b->same)
76       {
77         byte *z;
78         bputc(f, a->attr);
79         for(z = b->val; *z; z++)
80           if (*z >= ' ' || *z == '\t')
81             bputc(f, *z);
82           else
83             {
84               bputc(f, '?');
85               log(L_ERROR, "obj_dump: Found non-ASCII characters (URL might be %s)", obj_find_aval(d, 'U'));
86             }
87         ASSERT(z - b->val <= MAX_ATTR_SIZE-2);
88         bputc(f, '\n');
89       }
90 }
91
92 void
93 obj_write_nocheck(struct fastbuf *f, struct odes *d)
94 {
95   for(struct oattr *a=d->attrs; a; a=a->next)
96     for(struct oattr *b=a; b; b=b->same)
97       {
98         bputc(f, a->attr);
99         bputsn(f, b->val);
100       }
101 }
102
103 struct oattr *
104 obj_find_attr(struct odes *o, uns x)
105 {
106   struct oattr *a;
107   for(a=o->attrs; a && a->attr != x; a=a->next)
108     ;
109   return a;
110 }
111
112 struct oattr *
113 obj_find_attr_last(struct odes *o, uns x)
114 {
115   struct oattr *a = obj_find_attr(o, x);
116
117   if (a)
118     {
119       while (a->same)
120         a = a->same;
121     }
122   return a;
123 }
124
125 uns
126 obj_del_attr(struct odes *o, struct oattr *a)
127 {
128   struct oattr *x, **p, *y, *l;
129   byte aa = a->attr;
130
131   o->cached_attr = NULL;
132   p = &o->attrs;
133   while (x = *p)
134     {
135       if (x->attr == aa)
136         {
137           y = x;
138           l = NULL;
139           while (x = *p)
140             {
141               if (x == a)
142                 {
143                   *p = x->same;
144                   return 1;
145                 }
146               p = &x->same;
147               l = x;
148             }
149           return 0;
150         }
151       p = &x->next;
152     }
153   return 0;
154 }
155
156 byte *
157 obj_find_aval(struct odes *o, uns x)
158 {
159   struct oattr *a = obj_find_attr(o, x);
160
161   return a ? a->val : NULL;
162 }
163
164 struct oattr *
165 obj_set_attr(struct odes *o, uns x, byte *v)
166 {
167   struct oattr *a, **z;
168
169   z = &o->attrs;
170   while (a = *z)
171     {
172       if (a->attr == x)
173         {
174           *z = a->next;
175           goto set;
176         }
177       z = &a->next;
178     }
179
180  set:
181   if (v)
182     {
183       a = oa_new(o, x, v);
184       a->next = o->attrs;
185       o->attrs = a;
186     }
187   else
188     a = NULL;
189   o->cached_attr = a;
190   return a;
191 }
192
193 struct oattr *
194 obj_set_attr_num(struct odes *o, uns a, uns v)
195 {
196   byte x[32];
197
198   sprintf(x, "%d", v);
199   return obj_set_attr(o, a, x);
200 }
201
202 struct oattr *
203 obj_add_attr(struct odes *o, uns x, byte *v)
204 {
205   struct oattr *a, *b;
206
207   b = oa_new(o, x, v);
208   if (!(a = o->cached_attr) || a->attr != x)
209     {
210       if (!(a = obj_find_attr(o, x)))
211         {
212           b->next = o->attrs;
213           o->attrs = b;
214           goto done;
215         }
216     }
217   while (a->same)
218     a = a->same;
219   a->same = b;
220  done:
221   o->cached_attr = b;
222   return b;
223 }
224
225 struct oattr *
226 obj_prepend_attr(struct odes *o, uns x, byte *v)
227 {
228   struct oattr *a, *b, **z;
229
230   b = oa_new(o, x, v);
231   z = &o->attrs;
232   while (a = *z)
233     {
234       if (a->attr == x)
235         {
236           b->same = a;
237           b->next = a->next;
238           a->next = NULL;
239           *z = b;
240           return b;
241         }
242       z = &a->next;
243     }
244   b->next = o->attrs;
245   o->attrs = b;
246   return b;
247 }
248
249 struct oattr *
250 obj_insert_attr(struct odes *o, struct oattr *first, struct oattr *after, byte *v)
251 {
252   struct oattr *b = oa_new(o, first->attr, v);
253   b->same = after->same;
254   after->same = b;
255   return b;
256 }
257
258 void
259 obj_move_attr_to_head(struct odes *o, uns x)
260 {
261   struct oattr *a, **z;
262
263   z = &o->attrs;
264   while (a = *z)
265     {
266       if (a->attr == x)
267         {
268           *z = a->next;
269           a->next = o->attrs;
270           o->attrs = a;
271           break;
272         }
273       z = &a->next;
274     }
275 }
276
277 void
278 obj_move_attr_to_tail(struct odes *o, uns x)
279 {
280   struct oattr *a, **z;
281
282   z = &o->attrs;
283   while (a = *z)
284     {
285       if (a->attr == x)
286         {
287           *z = a->next;
288           while (*z)
289             z = &(*z)->next;
290           *z = a;
291           a->next = NULL;
292           break;
293         }
294       z = &a->next;
295     }
296 }