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